package com.jinlia.show.modules.system.service;

import com.jinlia.show.common.core.exception.MyRuntimeException;
import com.jinlia.show.common.core.utils.UserInfoUtils;
import com.jinlia.show.modules.base.constant.*;
import com.jinlia.show.modules.base.model.po.OrderItemPO;
import com.jinlia.show.modules.base.model.po.OrderPO;
import com.jinlia.show.modules.base.service.WxMessageService;
import com.jinlia.show.modules.base.system.entity.DeliveryOrder;
import com.jinlia.show.modules.base.system.entity.Order;
import com.jinlia.show.modules.base.system.entity.OrderItem;
import com.jinlia.show.modules.base.system.entity.OrderRefund;
import com.jinlia.show.modules.base.system.service.*;
import com.jinlia.show.modules.base.utils.OrderNumGenerator;
import com.jinlia.show.modules.base.utils.PayOrderNumGenerator;
import com.jinlia.show.modules.base.wxapp.entity.PayOrder;
import com.jinlia.show.modules.base.wxapp.service.PayOrderMapperService;
import com.jinlia.show.modules.system.model.forms.SysOrderForm;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 下单逻辑分工（前端和后端）
 * 前端：计算订单的，原价金额(必填)，折扣金额（选），抹零金额（选），应收金额（必填） {应收金额 = 原价金额-折扣金额-抹零金额}
 * if(原价金额 != 应收金额) ==> 折扣金额（必填）
 * 后端：结算时计算item项
 */
@Slf4j
@Service
public class OrderService {
    @Value("${wxapp.version}")
    public String wxappVersion;
    @Autowired
    OrderMapperService orderMapperService;
    @Autowired
    OrderItemMapperService orderItemMapperService;
    @Autowired
    GoodsMapperService goodsMapperService;

    @Autowired
    DeliveryOrderMapperService deliveryOrderMapperService;
    @Autowired
    OrderRefundMapperService orderRefundMapperService;
    @Autowired
    ScheduledExecutorService scheduledExecutorService;
    @Autowired
    OrderNumGenerator orderNumGenerator;
    @Autowired
    PayOrderNumGenerator payOrderNumGenerator;
    @Autowired
    WxMessageService wxMessageService;


    @Transactional
    public OrderRefund cancelOrder(OrderRefund refundOrder) {
        Order byIdOrder = orderMapperService.getById(refundOrder.getOrderId());
        // 参数验证
        if (refundOrder.getRefundMoney().compareTo(BigDecimal.ZERO) <= 0 ||
                byIdOrder.getReceivedMoney().compareTo(BigDecimal.ZERO) <= 0) {
            throw new MyRuntimeException("退款金额或已收金额不合法");
        }
        // 校验退款金额
        BigDecimal totalRefundedMoney = byIdOrder.getRefundedMoney().add(refundOrder.getRefundMoney());
        if (totalRefundedMoney.compareTo(byIdOrder.getReceivedMoney()) > 0) {
            BigDecimal maxRefundableAmount = byIdOrder.getReceivedMoney().subtract(byIdOrder.getRefundedMoney())
                    .setScale(2, RoundingMode.HALF_UP);
            throw new MyRuntimeException("申请退款金额不能大于" + maxRefundableAmount);
        }
        /**
         * 校验是否有待处理的退款单
         */
        List<OrderRefund> listOrderRefund = orderRefundMapperService.lambdaQuery()
                .eq(OrderRefund::getOrderId, byIdOrder.getId())
                .eq(OrderRefund::getRefundStatus, OrderPayStatusEnum.REFUNDING.getValue())
                .list();
        if (!CollectionUtils.isEmpty(listOrderRefund)) {
            throw new MyRuntimeException("有待处理的退款单!!!");
        }
        refundOrder.setRefundedMoney(BigDecimal.ZERO);//已退金额
        refundOrder.setRefundStatus(OrderPayStatusEnum.REFUNDING.getValue());//退款中
        orderRefundMapperService.save(refundOrder);
        orderMapperService.lambdaUpdate()
                .eq(Order::getId, byIdOrder.getId())
                .set(Order::getEnableStatus, EnableStatusEnum.AFTER_SALE.getValue())
                .set(Order::getPayStatus, OrderPayStatusEnum.REFUNDING.getValue())
                .update(new Order());
        // 日志记录
        log.info("订单 {} 的退款申请已提交", refundOrder.getOrderId());
        return refundOrder;
    }

    public void confirmOrder(Long id) {
        Order byId = orderMapperService.getById(id);
        /**
         * 校验订单状态
         */
        if (byId.getOrderStatus() != OrderStatusEnum.STEP_0.getValue()) {
            throw new MyRuntimeException("订单状态不合法");
        }
        orderMapperService.lambdaUpdate()
                .eq(Order::getId, id)
                .set(Order::getOrderStatus, OrderStatusEnum.STEP_1.getValue())
                .set(Order::getConfirmUserId, UserInfoUtils.getUserId())
                .update();
        //微信消息推送
        scheduledExecutorService.schedule(() -> {
            log.info(String.format("schedule当前线程=%S,延迟=%S", Thread.currentThread().getName(), "不延迟"));
            try {
                String body = wxMessageService.sendConfirmOrderMsg(id, wxappVersion);
                log.info("schedule当前线程={},消息模版推送结果={}", Thread.currentThread().getName(), body);
            } catch (Exception e) {
                log.error("chedule当前线程=%S,消息模版推送结果::", e);
            }
        }, 0, TimeUnit.SECONDS);
    }

    /**
     * 订单制作完成
     *
     * @param id d订单id
     * @return
     */
    public Boolean callOrder(Long id) {
        orderMapperService.lambdaUpdate()
                .eq(Order::getId, id)
                .set(Order::getOrderStatus, OrderStatusEnum.STEP_2.getValue())//待取货
                .update();
        return Boolean.TRUE;
    }

    public Boolean takeOrder(Long id) {
        Order byId = orderMapperService.getById(id);
        if (!OrderStatusEnum.STEP_2.getValue().equals(byId.getOrderStatus())) {
            throw new MyRuntimeException("非待取货状态");
        }
        //堂食订单
        if (DeliveryTypeEnum.SELF_PICT.getValue().equals(byId.getDeliveryType())) {
            orderMapperService.lambdaUpdate()
                    .eq(Order::getId, id)
                    .set(Order::getOrderStatus, OrderStatusEnum.STEP_4.getValue())//结束订单
                    .update();
        } else if (DeliveryTypeEnum.OTHER_PICT.getValue().equals(byId.getDeliveryType())) { //还未确认配送方式
            throw new MyRuntimeException("还未确认配送方式");
        } else {//外卖取餐
            orderMapperService.lambdaUpdate()
                    .eq(Order::getId, id)
                    .set(Order::getOrderStatus, OrderStatusEnum.STEP_3.getValue())
                    .update();
        }
        return Boolean.TRUE;
    }

    public Boolean finishOrder(Long id) {
        orderMapperService.lambdaUpdate()
                .eq(Order::getId, id)
                .set(Order::getOrderStatus, OrderStatusEnum.STEP_4.getValue())//结束订单
                .update();
        //更新配送单
        DeliveryOrder byIdDeliveryOrder = deliveryOrderMapperService.lambdaQuery()
                .eq(DeliveryOrder::getOrderId, id)
                .last("limit 1")
                .one();
        if (byIdDeliveryOrder != null) {
            deliveryOrderMapperService.lambdaUpdate()
                    .eq(DeliveryOrder::getId, byIdDeliveryOrder.getId())
                    .set(DeliveryOrder::getDeliveryStatus, DeliveryStatusEnum.E.getValue())
                    .update();
        }
        return Boolean.TRUE;
    }
    @Autowired
    private PayOrderMapperService payOrderMapperService;
    @Transactional
    public PayOrder createOrder(SysOrderForm sysOrderForm) {
        //构造数据
//        BigDecimal sumReceivableMoney = sysOrderForm.getOrderItems().stream().map(OrderItem::getReceivableMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        Order newOrder =(Order)sysOrderForm;
//        newOrder.setCompanyId(1l);
        newOrder.setDeliveryType(DeliveryTypeEnum.SELF_PICT.getValue());
        newOrder.setDeliveryMoney(BigDecimal.ZERO);
        orderMapperService.initOrder(newOrder);
        newOrder.setOrderNum(orderNumGenerator.nextId());
        orderMapperService.save(newOrder);
        //构造订单详情
        List<OrderItem> items = sysOrderForm.getOrderItems();
        List<OrderItem> orderItems = orderItemMapperService.initOrderItems(newOrder, items);
        orderItemMapperService.saveBatch(orderItems);
        //生成支付dan订单
        //生产支付单
        PayOrder payOrder = payOrderMapperService.createByOrder(newOrder);
        payOrder.setPayOrderNum(payOrderNumGenerator.nextId());
        payOrderMapperService.save(payOrder);
        return payOrder;
    }
}
